#include "screen.h"
#include "mario.h"

/* define small tile */
enum Tile {
    NONE = 0,
    WALL,
    TREE,
    CLOUD,
    PIPE,
    LAST
};

/* use these two values to define colors */
#define A 220
#define B 110

static const RGB TILE_COLORS[NUM_TILES] = {
	[NONE] = {0, 0, 16},
	[WALL] = {0, A, 0},
	[TREE] = {A, B, 0},
	[CLOUD] = {A, A, 0},
	[PIPE] = {A, 0, A},
	[LAST] = {B, B, B},
};

/* window state */
struct WINDOW_STATE {
	int x, y;  // location on world
} state;

enum Tile world[WORLD_HEIGHT][WORLD_WIDTH];

/* 4 bits for type of tile*/
#define TILE_MASK 0x0F

void world_init() {
	size_t x, y;
	memset(world, NONE, WORLD_WIDTH*WORLD_HEIGHT);
	for (y = 0; y < WORLD_HEIGHT; y++) {
		for (x = 0; x < WORLD_WIDTH; x++) {
			world[y][x] = rand()%NUM_TILES;
		}
	}
}

/* calculate which tile on window position (tx, ty) */
void * window_tile(int tx, int ty) {
	int wx = state.x + tx;  // world x
	int wy = state.y + ty;	// world y
	// which tile on (wx, wy)?
	if ( wx<0 || wx>=WORLD_WIDTH || wy<0 || wy>=WORLD_HEIGHT)
		return NONE;
	return (void*)(world[wy][wx]);
}

/* location (tx, ty)'s unit is tile, not pixel,
   origin point is the top-left of the window */
_Bool window_render(int tx, int ty) {
	/* tile color */
	enum Tile tile = (enum Tile)window_tile(tx,ty) & TILE_MASK;
	setcolor(TILE_COLORS[tile].r, TILE_COLORS[tile].g, TILE_COLORS[tile].b);
	fillrect(tx * TILE_SIZE + 1, ty * TILE_SIZE + 1, TILE_SIZE - 2, TILE_SIZE - 2);
	return true;
}

void window_move(int dx, int dy) {
	if(state.x+dx>-10 && state.x+dx<WORLD_WIDTH-WINDOW_WIDTH+10 )
		state.x += dx;
	if(state.y+dy>-10 && state.y+dy<WORLD_HEIGHT-WINDOW_HEIGHT+10 )
		state.y += dy;
}

void window_moveto(int wx, int wy) {
	state.x = wx;
	state.y = wy;
}

